# -*- encoding: utf-8 -*-

"""
@File:      tc_libfastjson_libfastjson_func_005.py
@Time:      2024/04/01 14:33:20
@Author:    chenchunhu
@Version:   1.0
@Contact:   wb-cch358909@alibaba-inc.com
@License:   Mulan PSL v2
@Modify:    chenchunhu
"""

from common.basetest import LocalTest

class Test(LocalTest):
    """
    See tc_libfastjson_libfastjson_func_005.yaml for details

    :avocado: tags=P2,noarch,local,fix
    """

    PARAM_DIC = {"pkg_name": "libfastjson libfastjson-devel gcc"}
    def setUp(self):
        super().setUp(self.PARAM_DIC)
        cmdline = '''cat >fjson_test5.c<<"EOF"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libfastjson/json.h>

// 函数用于创建一个具有多层嵌套和不同数据类型的复杂 JSON 对象
fjson_object *create_complex_json_object(int depth) {
    if (depth < 1) {
        return NULL;
    }
    
    fjson_object *json_obj = fjson_object_new_object();
    fjson_object_object_add(json_obj, "int_val", fjson_object_new_int(depth));
    fjson_object_object_add(json_obj, "string_val", fjson_object_new_string("test string"));
    
    fjson_object *arr_obj = fjson_object_new_array();
    for (int i = 0; i < depth; ++i) {
        fjson_object_array_add(arr_obj, fjson_object_new_int(i));
    }
    fjson_object_object_add(json_obj, "array_val", arr_obj);
    
    if (depth > 1) {
        fjson_object *child_obj = create_complex_json_object(depth - 1); // 递归创建子对象
        fjson_object_object_add(json_obj, "nested_val", child_obj);
    }
    
    return json_obj;
}

// 函数用于深度比较两个 JSON 对象是否相等
int compare_json_objects(fjson_object *obj1, fjson_object *obj2) {
    if (!obj1 || !obj2) {
        return 0;
    }
    
    if (fjson_object_get_type(obj1) != fjson_object_get_type(obj2)) {
        return 0;
    }

    switch (fjson_object_get_type(obj1)) {
        case fjson_type_object: {
            fjson_object *val1, *val2;
            fjson_object_iter it;
            struct fjson_object_iterator itBegin = fjson_object_iter_begin(obj1);
            struct fjson_object_iterator itEnd = fjson_object_iter_end(obj1);
            
            while (!fjson_object_iter_equal(&itBegin, &itEnd)) {
                const char *key = fjson_object_iter_peek_name(&itBegin);
                val1 = fjson_object_iter_peek_value(&itBegin);
                if (!fjson_object_object_get_ex(obj2, key, &val2)) {
                    return 0;
                }
                if (!compare_json_objects(val1, val2)) {
                    return 0;
                }
                fjson_object_iter_next(&itBegin);
            }
            break;
        }
        case fjson_type_array: {
            int len1 = fjson_object_array_length(obj1);
            int len2 = fjson_object_array_length(obj2);
            if (len1 != len2) return 0;
            for (int i = 0; i < len1; i++) {
                if (!compare_json_objects(
                        fjson_object_array_get_idx(obj1, i),
                        fjson_object_array_get_idx(obj2, i))) {
                    return 0;
                }
            }
            break;
        }
        case fjson_type_int:
            return fjson_object_get_int(obj1) == fjson_object_get_int(obj2);
        case fjson_type_boolean:
            return fjson_object_get_boolean(obj1) == fjson_object_get_boolean(obj2);
        case fjson_type_double:
            return fjson_object_get_double(obj1) == fjson_object_get_double(obj2);
        case fjson_type_string:
            return strcmp(fjson_object_get_string(obj1), fjson_object_get_string(obj2)) == 0;
        default:
            return 0; // 无默认比较方法
    }
    return 1;
}

int main() {
    // 指定不同的复杂度级别来测试
    const int complexity_levels[] = {1, 2, 3, 5, 8};
    const int num_levels = sizeof(complexity_levels)/sizeof(complexity_levels[0]);
    
    for (int i = 0; i < num_levels; ++i) {
        int level = complexity_levels[i];
        printf("Testing JSON complexity level %d\\n", level);
        
        // 生成复杂的 JSON 对象
        fjson_object *json_obj = create_complex_json_object(level);
        if (!json_obj) {
            fprintf(stderr, "Failed to create complex JSON object\\n");
            return EXIT_FAILURE;
        }
        
        // 转换为 JSON 字符串
        const char *json_str = fjson_object_to_json_string(json_obj);

        // 从字符串解析回 JSON 对象
        fjson_object *parsed_json = fjson_tokener_parse(json_str);
        if (!parsed_json) {
            fprintf(stderr, "Failed to parse back JSON string\\n");
            fjson_object_put(json_obj); // 清理资源
            return EXIT_FAILURE;
        }
        
        // 比较原始对象和解析回来的对象
        if (!compare_json_objects(json_obj, parsed_json)) {
            fprintf(stderr, "Parsed JSON object does not match the original at level %d\\n", level);
            fjson_object_put(json_obj); // 清理资源
            fjson_object_put(parsed_json); // 清理资源
            return EXIT_FAILURE;
        }
        
        // 清理资源
        fjson_object_put(json_obj);
        fjson_object_put(parsed_json);
        
        printf("JSON complexity level %d passed\\n", level);
    }
    
    printf("All tests passed\\n");
    return EXIT_SUCCESS;
}
EOF'''
        self.cmd(cmdline)


    def test(self):
        self.cmd("gcc -o fjson_test5 fjson_test5.c -lfastjson")
        code, fjson_result = self.cmd("./fjson_test5")
        self.assertIn('All tests passed', fjson_result)

    def tearDown(self):
        super().tearDown(self.PARAM_DIC)
        self.cmd("rm -rf fjson_test5.c fjson_test5")
